//
//  RZVoiceMessageCell.m
//  RZIM
//
//  Created by reyzhang on 2021/8/23.
//

#import "RZVoiceMessageCell.h"
#import "RZKitCommonDefine.h"
#import "RZKitUtility.h"
#import "RZMessageCellTool.h"
#import "RZVoicePlayer.h"
#import "NetworkTools.h"


#define Voice_Height 40
#define voice_Unread_View_Width 8
#define Play_Voice_View_Width 16


static NSTimer *s_previousAnimationTimer = nil;
static UIImageView *s_previousPlayVoiceImageView = nil;
static RZMessageDirection s_previousMessageDirection;
static long s_messageId = 0;


@interface RZVoiceMessageCell()<RZVoicePlayerObserver>
@property (nonatomic) long duration;

@property (nonatomic) CGSize voiceViewSize;

@property (nonatomic) int animationIndex;

@property (nonatomic, strong) NSTimer *animationTimer;

@property (nonatomic, strong) RZVoicePlayer *voicePlayer;
@end

@implementation RZVoiceMessageCell

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initialize];
    }
    return self;
}

- (void)dealloc {
    [self disableCurrentAnimationTimer];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Public Methods

- (void)playVoice {

    [self disablePreviousAnimationTimer];

    if (self.model.mid == s_messageId) {
        if (self.voicePlayer.isPlaying) {
            [self.voicePlayer stopPlayVoice];
//            [self startDestruct];
        } else {
            [self startPlayingVoiceData];
//            [self stopDestruct];
        }
    } else {
        [self startPlayingVoiceData];
//        [self stopDestruct];
    }
}

- (void)stopPlayingVoice {
    if (self.model.mid == s_messageId) {
        if (self.voicePlayer.isPlaying) {
            [self stopPlayingVoiceData];
            [self disableCurrentAnimationTimer];
        }
    }
}

#pragma mark - Super Methods

+ (CGSize)sizeForMessageModel:(RZMessageInfo *)model
      withCollectionViewWidth:(CGFloat)collectionViewWidth
         referenceExtraHeight:(CGFloat)extraHeight {
    CGFloat messagecontentview_height = Voice_Height;

    if (messagecontentview_height < RZIMConfigCenter.ui.globalMessagePortraitSize.height) {
        messagecontentview_height = RZIMConfigCenter.ui.globalMessagePortraitSize.height;
    }

    messagecontentview_height += extraHeight;

    return CGSizeMake(collectionViewWidth, messagecontentview_height);
}

- (void)resetAnimationTimer{
    if (s_messageId == self.model.mid) {
        if ((self.voicePlayer.isPlaying)) {
            [self disableCurrentAnimationTimer];
            [self enableCurrentAnimationTimer];
        }
    } else {
        [self disableCurrentAnimationTimer];
    }
}


- (void)setMessageInfo:(RZMessageInfo *)message{
    if (message) {
        NSInteger second = 1;
        if (message.extraInfo && [message.extraInfo isKindOfClass:[RZVoiceMessageModel class]]) {
            RZVoiceMessageModel *model  =  (RZVoiceMessageModel *)message.extraInfo;
            second = MAX(model.duration,1);
        }
        self.voiceDurationLabel.text = [NSString stringWithFormat:@"%ld''", (long)second];
    } else {
        NSLog(@"RZMessageModel.content is NOT RZHQVoiceMessage object");
    }
}

- (CGFloat)getBubbleWidth:(long)duration{
    CGFloat audioBubbleWidth =
        kAudioBubbleMinWidth +
        (kAudioBubbleMaxWidth - kAudioBubbleMinWidth) * duration / 60; //默认录制时长
    audioBubbleWidth = audioBubbleWidth > kAudioBubbleMaxWidth ? kAudioBubbleMaxWidth : audioBubbleWidth;
    return audioBubbleWidth;
}

- (void)updateSubViewsLayout:(RZMessageInfo *)voiceMessage{
    
    NSInteger second = 1;
    if (voiceMessage.extraInfo && [voiceMessage.extraInfo isKindOfClass:[RZVoiceMessageModel class]]) {
        RZVoiceMessageModel *model  =  (RZVoiceMessageModel *)voiceMessage.extraInfo;
        second = MAX(model.duration,1);
    }
    CGFloat audioBubbleWidth = [self getBubbleWidth:second]; //
    self.messageContentView.contentSize = CGSizeMake(audioBubbleWidth, Voice_Height);
    if (self.model.messageDirection == MessageDirection_SEND) {
        
        self.voiceDurationLabel.textAlignment = NSTextAlignmentRight;
         self.playVoiceView.frame = CGRectMake(self.messageContentView.frame.size.width-12-Play_Voice_View_Width, (Voice_Height - Play_Voice_View_Width)/2, Play_Voice_View_Width, Play_Voice_View_Width);
        
        self.voiceDurationLabel.frame = CGRectMake(12, 0, CGRectGetMinX(self.playVoiceView.frame) - 20, Voice_Height);
        [self.voiceDurationLabel setTextColor:RGBCOLOR(38, 49, 62)];
        self.playVoiceView.image = RZResourceImage(@"to_voice_3");
    }else{
        self.playVoiceView.image = RZResourceImage(@"from_voice_3");
        [self.voiceDurationLabel setTextColor:RGBCOLOR(38, 49, 62)];
         self.voiceDurationLabel.textAlignment = NSTextAlignmentLeft;
         self.playVoiceView.frame = CGRectMake(12, (Voice_Height - Play_Voice_View_Width)/2, Play_Voice_View_Width, Play_Voice_View_Width);
         self.voiceDurationLabel.frame = CGRectMake(CGRectGetMaxX(self.playVoiceView.frame) + 8, 0, audioBubbleWidth - (CGRectGetMaxX(self.playVoiceView.frame) + 8), Voice_Height);
     }
    
//    [self addVoiceUnreadTagView];
}


- (void)setDataModel:(RZMessageInfo *)model {
    [super setDataModel:model];
    [self resetAnimationTimer];

    [self setMessageInfo:model];
    [self updateSubViewsLayout:model];
}

#pragma mark - RCVoicePlayerObserver
- (void)PlayerDidFinishPlaying:(BOOL)isFinish {
    if (isFinish) {
        [self disableCurrentAnimationTimer];
    }
}

- (void)audioPlayerDecodeErrorDidOccur:(NSError *)error {
    [self disableCurrentAnimationTimer];
}


#pragma mark - Notification

- (void)registerNotification{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(resetActiveEventInBackgroundMode)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(resetByExtensionModelEvents)
                                                 name:@"RZKitExtensionModelResetVoicePlayingNotification"
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(stopPlayingVoiceDataIfNeed:)
                                                 name:kNotificationStopVoicePlayer
                                               object:nil];
}

- (void)playVoiceNotification:(NSNotification *)notification {
    long messageId = [notification.object longValue];
    if (messageId == self.model.mid) {
        [self playVoice];
    }
}

// todo cyenux
- (void)resetByExtensionModelEvents {
    [self stopPlayingVoiceData];
    [self disableCurrentAnimationTimer];
}

// stop and disable timer during background mode.
- (void)resetActiveEventInBackgroundMode {
    [self stopPlayingVoiceData];
    [self disableCurrentAnimationTimer];
}

#pragma mark - Private Methods

- (void)initialize {
    [self showBubbleBackgroundView:YES];
    [self.messageContentView addSubview:self.playVoiceView];
    [self.messageContentView addSubview:self.voiceDurationLabel];

    self.voicePlayer = [RZVoicePlayer defaultPlayer];
    [self registerNotification];
}

- (void)stopPlayingVoiceDataIfNeed:(NSNotification *)notification {
    long messageId = [notification.object longValue];
    if (messageId == self.model.mid) {
        [self disableCurrentAnimationTimer];
//        [self startDestruct];
    }
}

- (void)startPlayingVoiceData {
    NSURL *fileUrl = [NSURL URLWithString:self.model.msg];
    if (!fileUrl) {
        return;
    }
    
    //将文件流下载到本地，再播放
    [NetworkTools downloadFileWithUrl:fileUrl completeHandler:^(NSURL * _Nonnull localUrl) {
        //录音格式转换，从amr转为wav
        /*NSString *wavFilePath = [[localUrl.path stringByDeletingPathExtension]
                                 stringByAppendingPathExtension:@"wav"];
        BOOL convertResult = YES;
        if (![RZKitUtility isFileExist:wavFilePath]) {
            convertResult = [RZKitUtility convertAMR:localUrl.path toWAV:wavFilePath];
        }
        if (!convertResult) {
            return;
        }
        NSData * wavAudioData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:wavFilePath]];*/
        NSData *mp3Data = [NSData dataWithContentsOfURL:localUrl];
        if (mp3Data) {
            /**
             *  if the previous voice message is playing, then
             *  stop it and reset the prevoius animation timer indicator
             */
            BOOL bPlay = [self.voicePlayer playVoice:self.model.conversationType
                                            targetId:self.model.gid
                                           messageId:self.model.mid
                                           direction:self.model.messageDirection
                                           voiceData:mp3Data
                                            observer:self];
            // if failed to play the voice message, reset all indicator.
            if (!bPlay) {
                [self stopPlayingVoiceData];
                [self disableCurrentAnimationTimer];
            } else {
                [self enableCurrentAnimationTimer];
            }
            s_messageId = self.model.mid;
        } else {
            NSLog(@" RZMessageInfo.voiceData is NULL");
        }
    }];
}

- (void)stopPlayingVoiceData {
    if (self.voicePlayer.isPlaying) {
        [self.voicePlayer stopPlayVoice];
    }
}
- (void)enableCurrentAnimationTimer {
    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                           target:self
                                                         selector:@selector(scheduleAnimationOperation)
                                                         userInfo:nil
                                                          repeats:YES];
    [self.animationTimer fire];

    s_previousAnimationTimer = self.animationTimer;
    s_previousPlayVoiceImageView = self.playVoiceView;
    s_previousMessageDirection = self.model.messageDirection;
}

/**
 *  Implement the animation operation
 */
- (void)scheduleAnimationOperation {
    NSLog(@"%s", __FUNCTION__);

    self.animationIndex++;
    NSString *playingIndicatorIndex;
    if (MessageDirection_SEND == self.model.messageDirection) {
        playingIndicatorIndex = [NSString stringWithFormat:@"to_voice_%d", (self.animationIndex % 4)];
    } else {
        playingIndicatorIndex = [NSString stringWithFormat:@"from_voice_%d", (self.animationIndex % 4)];
    }
    NSLog(@"playingIndicatorIndex > %@", playingIndicatorIndex);
    self.playVoiceView.image = RZResourceImage(playingIndicatorIndex);
}

- (void)disableCurrentAnimationTimer {
    if (self.animationTimer && [self.animationTimer isValid]) {
        [self.animationTimer invalidate];
        self.animationTimer = nil;
        self.animationIndex = 0;
    }
    if (MessageDirection_SEND == self.model.messageDirection) {
        self.playVoiceView.image = RZResourceImage(@"to_voice_3");
    } else {
        self.playVoiceView.image = RZResourceImage(@"from_voice_3");
    }
}

- (void)disablePreviousAnimationTimer {
    if (s_previousAnimationTimer && [s_previousAnimationTimer isValid]) {
        [s_previousAnimationTimer invalidate];
        s_previousAnimationTimer = nil;

        /**
         *  reset the previous playVoiceView indicator image
         */
        if (s_previousPlayVoiceImageView) {
            if (MessageDirection_SEND == self.model.messageDirection) {
                s_previousPlayVoiceImageView.image = RZResourceImage(@"to_voice_3");
            } else {
                s_previousPlayVoiceImageView.image = RZResourceImage(@"from_voice_3");
            }
            s_previousPlayVoiceImageView = nil;
            s_previousMessageDirection = 0;
        }
    }
}

#pragma mark - Getter

- (RZVoicePlayer *)voicePlayer{
    if (!_voicePlayer) {
        _voicePlayer = [RZVoicePlayer defaultPlayer];
    }
    return _voicePlayer;
}

- (UIImageView *)playVoiceView{
    if (!_playVoiceView) {
        _playVoiceView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _playVoiceView.image = RZResourceImage(@"play_voice");

    }
    return _playVoiceView;
}

- (UILabel *)voiceDurationLabel{
    if (!_voiceDurationLabel) {
        _voiceDurationLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        _voiceDurationLabel.textAlignment = NSTextAlignmentLeft;
        _voiceDurationLabel.font = [RZIMConfigCenter.font fontOfGuideLevel];
    }
    return _voiceDurationLabel;
}

@end
